package fr.upstlse.glre.client.espacededie.commun.communiquer.action;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Html;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.toolbar.TextToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Label;

import fr.upstlse.glre.client.constante.fields.MessageConstante;
import fr.upstlse.glre.client.espacededie.commun.communiquer.Ecrire;
import fr.upstlse.glre.client.espacededie.commun.communiquer.Lire;
import fr.upstlse.glre.client.espacededie.commun.communiquer.Message;
import fr.upstlse.glre.client.utilitaires.ControlerUtil;
import fr.upstlse.glre.client.vo.communiquer.MessageEtatGWT;
import fr.upstlse.glre.client.vo.communiquer.MessageVOGWT;
import fr.upstlse.glre.client.widgets.modelData.MessageModelData;

public class ViewerSelectionAction implements Listener<ComponentEvent> {

	private MessageVOGWT messageVOGWT;
	private ContentPanel corps;
	List<MessageVOGWT> sortedMessageVOGWT = new LinkedList<MessageVOGWT>();
	
	private static ReadPanel readPanelInstance;

	public void handleEvent(ComponentEvent pBe) {
		corps = Message.getInstance().getCorps();
		MessageModelData lMessageModelData = (MessageModelData) Lire
				.getInstance().getLirePanel().getSelectedItem().getModel();
		updateMessageEtat(lMessageModelData);
		if (lMessageModelData != null) {
			Lire.getInstance().getLirePanel().setVisible(false);
			messageVOGWT = lMessageModelData.toMessageVOGWT();
			corps.add(new ReadPanel());
			corps.layout();
		}
	}

	class ReadPanel extends LayoutContainer {

		public ReadPanel() {
			readPanelInstance = this;
		}

		@Override
		protected void onRender(Element pParent, int pIndex) {
			super.onRender(pParent, pIndex);

			setSortedMessageVOGWT();
			int lDisplayed = 0;

			for (MessageVOGWT lMessageVOGWT : sortedMessageVOGWT) {
				MessagePanel lMessagePanel = new MessagePanel(lMessageVOGWT);
					if (lDisplayed == sortedMessageVOGWT.size() -1) {
						lMessagePanel.add(new MessageBar(lMessageVOGWT));
						lMessagePanel.add(new HeaderPanel(lMessageVOGWT));
						lMessagePanel.add(new ContenuPanel(lMessageVOGWT));
						lMessagePanel.add(new MessageBar(lMessageVOGWT));
					} 
					else {
						lMessagePanel.collapse();
						lMessagePanel.add(new HeaderPanel(lMessageVOGWT));
						lMessagePanel.add(new ContenuPanel(lMessageVOGWT));
					}
				
				add(lMessagePanel);
				lDisplayed++;
			}
		}
		
		
		class MessagePanel extends ContentPanel {
			private MessageVOGWT currentMessageVOGWT;
			
			public MessagePanel(MessageVOGWT pMessageVOGWT) {
				currentMessageVOGWT = pMessageVOGWT;
				createMessagePanel();
			}

			private void createMessagePanel() {
				setCollapsible(true);
				setHeading( currentMessageVOGWT.getTitre());
			}
		}

		class HeaderPanel extends ContentPanel {
			private MessageVOGWT currentMessageVOGWT;
			public HeaderPanel(MessageVOGWT pMessageVOGWT) {
				currentMessageVOGWT = pMessageVOGWT;
				createHeader();
				
			}

			private void createHeader() {
				setHeaderVisible(false);
				
				String lDeText = MessageConstante.LABEL_DE_TEXT.getValue()
						+ ": " + currentMessageVOGWT.getExpediteur().getLogin();
				Label lDeLabel = new Label();
				lDeLabel.setText(lDeText);
				add(lDeLabel);

				String lDateText = MessageConstante.LABEL_DATE_TEXT.getValue()
						+ ": " + currentMessageVOGWT.getDate();
				Label lDateLabel = new Label();
				lDateLabel.setText(lDateText);
				add(lDateLabel);

				String lObjetText = MessageConstante.LABEL_OBJET_TEXT
						.getValue()
						+ ": " + currentMessageVOGWT.getTitre();
				Label lObjetLabel = new Label();
				lObjetLabel.setText(lObjetText);
				add(lObjetLabel);
			}
		}

		class ContenuPanel extends ContentPanel {
			private MessageVOGWT currentMessageVOGWT;
			public ContenuPanel(MessageVOGWT pMessageVOGWT) {
				currentMessageVOGWT = pMessageVOGWT;
				createContenu();
			}

			private void createContenu() {
				setHeaderVisible(false);

				Html lHtml = new Html();
				lHtml.setHtml(currentMessageVOGWT.getContenu());
				add(lHtml);
			}
		}

		class MessageBar extends ToolBar {
			private MessageVOGWT currentMessageVOGWT;
			
			public MessageBar(MessageVOGWT pMessageVOGWT) {
				super();
				currentMessageVOGWT = pMessageVOGWT;
			}
			
			@Override
			protected void onRender(Element pTarget, int pIndex) {
				super.onRender(pTarget, pIndex);

				TextToolItem lRepondreToolItem = new TextToolItem();
				lRepondreToolItem.setId(MessageConstante.TOOLBAR_REPONDRE_ID
						.getValue());
				lRepondreToolItem
						.setText(MessageConstante.TOOLBAR_REPONDRE_TEXT
								.getValue());
				lRepondreToolItem
						.addSelectionListener(new SelectionListener<ComponentEvent>() {

							@Override
							public void componentSelected(ComponentEvent pCe) {
								corps.add(new RepondrePanel(currentMessageVOGWT));
								corps.layout();
							}

						});
				add(lRepondreToolItem);

				TextToolItem lSupprimerToolItem = new TextToolItem();
				lSupprimerToolItem.setId(MessageConstante.TOOLBAR_SUPPRIMER_ID
						.getValue());
				lSupprimerToolItem
						.setText(MessageConstante.TOOLBAR_SUPPRIMER_TEXT
								.getValue());
				add(lSupprimerToolItem);
			}

		}

		class RepondrePanel extends Ecrire {
			private MessageVOGWT currentMessageVOGWT;
			public RepondrePanel(MessageVOGWT pMessageVOGWT){
				super();
				currentMessageVOGWT = pMessageVOGWT;
			}
			
			@Override
			protected void onRender(Element pTarget, int pIndex) {
				super.onRender(pTarget, pIndex);

				getASuggestBox().setText(
						currentMessageVOGWT.getExpediteur().getLogin());
				getObjetTextField().setValue(currentMessageVOGWT.getTitre());
				getRichTextArea().setHTML(currentMessageVOGWT.getContenu());
				getEnvoyerButtonHaut().removeAllListeners();
				getEnvoyerButtonHaut().addSelectionListener(
						new RepondreButtonListener());
				getEnvoyerButtonBas().removeAllListeners();
				getEnvoyerButtonBas().addSelectionListener(
						new RepondreButtonListener());
			}

			protected class RepondreButtonListener extends
					SelectionListener<ComponentEvent> {

				@Override
				public void componentSelected(ComponentEvent pCe) {
					MessageVOGWT lReponseVOGWT = new MessageVOGWT();
					lReponseVOGWT.setTitre(getObjetTextField().getValue());
					lReponseVOGWT.setContenu(getRichTextArea().getHTML());
					lReponseVOGWT.setDate(new Date());
					lReponseVOGWT.setExpediteur(Message.getInstance()
							.getUserVOGWT());
					lReponseVOGWT.setParent(currentMessageVOGWT);
					final MessageBox lAttenteMessageBox = MessageBox.wait(
							"Chargement", "Envoi en cours...",
							"Veuillez patienter...");
					AsyncCallback<Object> lAsyncCallback = new AsyncCallback<Object>() {

						public void onFailure(Throwable pArg0) {
							lAttenteMessageBox.hide();
							MessageBox.alert("Erreur repondre ", pArg0
									.getMessage(), null);
						}

						public void onSuccess(Object pArg0) {
							lAttenteMessageBox.hide();
							Info.display("Information", "Envoyé avec succès",
									"");
						}
					};
					ControlerUtil.getUserControlerServiceAsyncInstance()
							.repondre(currentMessageVOGWT, lReponseVOGWT,
									lAsyncCallback);
				}
			}

		}
	}

	public static ReadPanel getReadPanelInstance() {
		return readPanelInstance;
	}

	public static void setReadPanelInstance(ReadPanel pReadPanelInstance) {
		readPanelInstance = pReadPanelInstance;
	}
	private void setSortedMessageVOGWT() {
		addParentToSortedList(messageVOGWT);
		addFilsToSortedList(messageVOGWT.getFils());
 	}
	
	private void addParentToSortedList(MessageVOGWT lMessageVOGWT) {
		if(lMessageVOGWT.getParent() != null) {
			addParentToSortedList(lMessageVOGWT.getParent());
		}
		sortedMessageVOGWT.add(lMessageVOGWT);
	}
	
	private void addFilsToSortedList(MessageVOGWT lMessageVOGWT) {
		if(lMessageVOGWT != null) {
			sortedMessageVOGWT.add(lMessageVOGWT);
			if(lMessageVOGWT.getFils() != null) {
				addFilsToSortedList(lMessageVOGWT.getFils());
			}
		}
	}
	
	private void updateMessageEtat(MessageModelData pMessageModelData) {
		MessageEtatGWT lMessageEtatGWT = (MessageEtatGWT) pMessageModelData.get(MessageConstante.MODELDATA_ETAT.getValue());
		if(lMessageEtatGWT.equals(MessageEtatGWT.NOUVEAU)) {
			pMessageModelData.set(MessageConstante.MODELDATA_ETAT.getValue(), MessageEtatGWT.LU);
			
			MessageVOGWT lMessageVOGWT = pMessageModelData.toMessageVOGWT();
			AsyncCallback<Object> lAsyncCallback = new AsyncCallback<Object>() {

				public void onFailure(Throwable pArg0) {
					MessageBox.alert("Erreur mise à jour du message ", pArg0
							.getMessage(), null);
				}

				public void onSuccess(Object pArg0) {
					Info.display("Information", "Etat du message: 'LU'",
					"");
				}
				
			};
			ControlerUtil.getUserControlerServiceAsyncInstance().updateMessage(lMessageVOGWT, lAsyncCallback);
		}
	}

}
